package org.tigr.htc.server.sge;

/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

import org.ggf.drmaa.DrmaaException;
import org.ggf.drmaa.JobInfo;
import org.ggf.drmaa.Session;
import org.ggf.drmaa.SessionFactory;
import org.tigr.antware.shared.util.Logger;

/**
 * The class <code>DRMAAUtils</code> provides methods to establish and manage a connection
 * to the grid via DRMAA and also to query and manage jobs on the grid.
 *
 */
public class DRMAAUtils {
	
    private static Logger logger = new Logger(DRMAAUtils.class);
        
    private static SessionFactory sessionFactory = null;
	private static Session session = null;
    
	/**
	 * @throws DrmaaException
	 */
	public static void initSession() throws DrmaaException {
		// Create a Session factory object
		if (sessionFactory == null || session == null) {
			if (sessionFactory == null) {
				System.out.println("SessionFactory is null. Initializing it...");
				sessionFactory = SessionFactory.getFactory();
			}
			
			if (session == null) {
				System.out.println("Session is null. Initializing it...");
			}
				
			session = sessionFactory.getSession();
			
			// initialize session
			session.init(null);
		}
	}
	
	public synchronized static void stopDRMAAJob(String gridId) 
							throws DrmaaException {
		// Terminate the command. This method returns once the action 
		// has been acknowledged by the DRM system, but does not 
		// necessarily wait until the action has been completed.
		session.control(gridId, Session.TERMINATE);
	}
	
	public synchronized static void exitSession() throws DrmaaException {
		// Exit session
		session.exit();
	}
		
	public static String getTimeinHHmmSS(long minutes){
		 logger.debug("Converting " + minutes + " to HH:mm:SS format." );
	    	
	     // Convert the minutes to 'HH:mm" format by determining the
	     // number of hours and minutes
		 String timeStr = null;
	    	
		 // Get hours
		 long hours = minutes/60;
	    	
		 // Get the remaining minutes
		 long min = minutes%60;
	    	
		 // Build the time string. Seconds are always set to 00
		 timeStr = "" + hours + ":" + min + ":00";
		 logger.debug(minutes + " Converted to " + timeStr);
	     return timeStr;
	 }
	  
	public synchronized static JobInfo waitForDRMAAJob(String id, long timeout) 
							throws DrmaaException {

		logger.debug("Waiting for the job " + id + " with timeout " + timeout);
		// Create a Session factory object
		
		
		// Wait for the job with 'id' is complete and return the 
		return session.wait(id, timeout);
	}	 
	
	public static synchronized int getStatusFromDRMAA(String gridId) {
		if (logger.isDebugEnabled()) {
			logger.debug("In getStatusFromDRMAA.");
		}
		
		// Default status 
		int status = -1;
	
		try {
			if (logger.isDebugEnabled()) {
				logger.debug("Checking the status of the grid id " + gridId);
			}

			status = session.getJobProgramStatus(gridId);
		
			if (logger.isDebugEnabled()) {
				logger.debug("Status of grid id is " + status);
			}
		} catch (DrmaaException de) {
			// Do nothing.. 
			logger.warn("DRMAA Error: " + de.getMessage());
			logger.warn("Could not get the job state for " + gridId);
		}

		return status;
	}
	
	public static synchronized boolean doesJobExistOnGrid(String gridId) {
		if (logger.isDebugEnabled()) {
			logger.debug("In doesJobExistOnGrid.");
		}
		
		// Default status 
		boolean exists = false;
	
		try {
			if (logger.isDebugEnabled()) {
				logger.debug("Checking the status of the grid id " + gridId);
			}

			// Get the status from the grid.
			int status = session.getJobProgramStatus(gridId);

			if (logger.isDebugEnabled()) {
				logger.debug("Status of grid id " + gridId + " is " + status);
			}
			
			// The DRMAA implementation should always get the status of jobId from the DRM 
			// unless the status has already been determined to be FAILED or DONE. 
			// and the status has been successfully cached. Terminated jobs return a FAILED status.
			
			if (status != Session.DONE && status != Session.FAILED) {
				// This means that the job is still on the grid. 
				exists = true;
			}
		} catch (DrmaaException de) {
			// Do nothing.. 
			logger.info("DRMAA Error: " + de.getMessage());
			logger.info("Could not get the job state for " + gridId);
		}

		if (logger.isDebugEnabled()) {
			logger.debug(gridId + " exists on the grid :" + exists);
		}
		return exists;
	}		
}
